package android.FiltrosJava;

//import java.awt.RenderingHints;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;

public class RotateTransform extends AbstractImageBasic{
	protected double ang;
	
	public RotateTransform(double angle){
		setRotation(angle);
	}
	public void setRotation(double angle){
		ang = angle * Math.PI/180.0f;		
	}
			
	public BufferedImage applyFilter(BufferedImage src) {
		BufferedImage dst = null;
		int[] dimensions = computeDimension(src.getWidth(),src.getHeight(),ang);
		dst = new BufferedImage( dimensions[1], dimensions[0], BufferedImage.TYPE_4BYTE_ABGR);
		
		Graphics2D g2d = dst.createGraphics();		
		
		int px = (int) (src.getWidth() / 2.0f);
		int py = (int) (src.getHeight() / 2.0f);
		int tx = (int) ((dimensions[1] - src.getWidth()) / 2.0f);
		int ty = (int) ((dimensions[0] - src.getHeight()) / 2.0f);
				
		AffineTransform xform = new AffineTransform();		
		xform.setToRotation(ang,px,py);
		AffineTransformOp op = new AffineTransformOp(xform, AffineTransformOp.TYPE_BICUBIC);
		g2d.drawImage(src, op, tx, ty);
				
		return removeVazio(dst);
		//return (dst);		
    }
	
	public BufferedImage removeVazio(BufferedImage src){
		int minX = 0, minY = 0, maxX = 0, maxY = 0;

		WritableRaster raster = src.getRaster();
		int numBands = raster.getNumBands();
    	int[] imageData = new int[numBands];
    	int[] vetColunas = new int[src.getWidth()];
    	int[] vetLinhas = new int[src.getHeight()];
    	    	
    	for (int y = 0; y < src.getWidth(); y++){
			vetColunas[y] = 0;
		}
    	
    	for (int y = 0; y < src.getHeight(); y++){
			vetLinhas[y] = 0;
		}
    	
    	for ( int x = 0; x < src.getWidth(); x++ ) {
    		for ( int y = 0; y < src.getHeight(); y++ ) {
    			raster.getPixel(x,y,imageData);
    			if (imageData[numBands-1] != 0){
    				vetLinhas[y] = 1;
    				vetColunas[x] = 1;
    			}
    		}
    	}
    	    	
    	for (int x = 0; x < src.getWidth(); x++){
    		if (vetColunas[x] == 1){
    			minX = x;
    			break;
    		}    			
    	}
    	    	
    	for (int y = 0; y < src.getHeight(); y++){
    		if (vetLinhas[y] == 1){
    			minY = y;
    			break;
    		}    			
    	}
    	    	    	
    	for (int x = src.getWidth()-1; x >= 0; x--){
    		if (vetColunas[x] == 1){
    			maxX = x;
    			break;
    		}    			
    	}
    	    	
    	for (int y = src.getHeight()-1; y >= 0; y--){
    		if (vetLinhas[y] == 1){
    			maxY = y;
    			break;
    		}    			
    	}
    	
    	if ((maxX-minX < 1) || (maxY-minY < 1))
    		return src;
    	else
    		return src.getSubimage(minX, minY, maxX-minX, maxY-minY);
	}
	
	public int[] computeDimension(int x, int y, double ang){
		int[] dimensions = new int[2];//dimensions = {y, x};
		double menor, maior;		
		float px = x/2.0f;
		float py = y/2.0f;
		
		double[][] matrix = {				
				{Math.cos(ang), -Math.sin(ang), (px * (1.0f - Math.cos(ang)) + py * Math.sin(ang))},
				{Math.sin(ang),  Math.cos(ang), (py * (1.0f - Math.cos(ang)) - px * Math.sin(ang))},
				{0, 0, 1}
		};
		
		double[][] coord = {
				{0, 0, 0}, {0, x, 0}, {y, x, 0}, {y, 0, 0} 
		};
		
		double[][] coordTrans = new double[4][3];
		
		for (int p1 = 0; p1 < 4; p1++){
			for (int p2 = 0; p2 < 3; p2++){
				coordTrans[p1][p2] = 0;
				for (int p3 = 0; p3 < 3; p3++){
					coordTrans[p1][p2] = coordTrans[p1][p2] + (coord[p1][p3] * matrix[p3][p2]);					
				}
			}			
		}
		
		//procurar menor...
		for (int p1 = 0; p1 < 2; p1++){
			menor = coordTrans[0][p1];
			for (int p2 = 1; p2 < 4; p2++){
				if (menor > coordTrans[p2][p1])
					menor = coordTrans[p2][p1];				
			}
						
			maior = coordTrans[0][p1] - menor; 
			for (int p2 = 1; p2 < 4; p2++){
				if (maior < (coordTrans[p2][p1] - menor))
					maior = (coordTrans[p2][p1] - menor);					
			}
			
			dimensions[p1] = (int) maior;
		}	
				
		return dimensions;
	}
}